package org.yxjme.exbluetoothserver;

import android.annotation.SuppressLint;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Set;
import java.util.UUID;

public class ServerBluetoothSocketUtil {

    private Handler handler;
    private BluetoothAdapter adapter ;
    private BluetoothServerSocket serverSocket ;
    private BluetoothDevice device = null;
    private BluetoothSocket socket = null;

    public ServerBluetoothSocketUtil(Handler handler){
        this.handler = handler;
        adapter = BluetoothAdapter.getDefaultAdapter() ;
    }


    public void init() {
        if ((device = getDevice(adapter)) == null){
            sendMsg("暂无蓝牙配对");
            return;
        }else {
            /**
             * 1、
             * 当您需要连接两台设备时，其中一台设备必须通过保持开放的 BluetoothServerSocket 来充当服务器。
             * 获取服务的方法
             */
            try {
                serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord(device.getName(), UUID.fromString(ConstantUtils.SPP_UUID));
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (serverSocket!=null){
                    start();
                }else {
                    sendMsg("创建serverSocket失败！");
                }
            }
        }
    }



    private void sendMsg(String msg){
        if (handler!=null){
            Message message = Message.obtain() ;
            message.obj = msg ;
            handler.sendMessage(message);
        }
    }



    /**
     * 获取当前配对的蓝牙设备
     *
     * @param adapter
     * @return
     */
    private BluetoothDevice getDevice(BluetoothAdapter adapter) {
        BluetoothDevice device = null;
        @SuppressLint("MissingPermission")
        Set<BluetoothDevice> devices = adapter.getBondedDevices();
        if (devices!=null&&devices.size()>0){
            for (BluetoothDevice d:devices){
                if (d.getBondState()==BluetoothDevice.BOND_BONDED){
                    device = d ;
                    break;
                }
            }
        }
        return device ;
    }


    private void start(){
        new Thread(new Runnable() {
            @SuppressLint("MissingPermission")
            @Override
            public void run() {
                try {
                    /**
                     * 2、
                     * 如果阻塞就会一直停留在这儿
                     */
                    socket = serverSocket.accept();
                    /**
                     * 3、
                     * 读取客户端传递来的数据
                     */
                    InputStream in = socket.getInputStream();
                    OutputStream out = socket.getOutputStream();

                    /**
                     * 4、
                     * 阻塞获取消息长度
                     */
                    while (in.available() == 0);

                    /**
                     * 5、
                     * 将信息打印出来
                     */
                    String msg=manageConnectedSocket(in);

                    /**6、将信息反馈给客户端*/
                    responseClient(msg,out);

                } catch (IOException e) {
                    e.printStackTrace();
                    sendMsg(e.getMessage());
                }
                finally {
                    try {
                        socket.close();
                        socket = null ;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }finally {
                        start();
                    }
                }
            }
        }).start();
    }


    /**
     * 反馈信息给发送方
     *
     * @param out
     */
    private void responseClient(String msg , OutputStream out) throws IOException {
        out.write(new StringBuffer()
                .append("{")
                .append("msg:"+msg)
                .append("}")
                .toString()
                .getBytes("utf-8"));
    }


    /**
     * @param in
     * @throws IOException
     */
    private String manageConnectedSocket(InputStream in) throws IOException {
        byte[] buff = new byte[in.available()] ;
        in.read(buff) ;
        String result = new String(buff) ;
        if (!TextUtils.isEmpty(result)){
            sendMsg(result);
        }
        return result ;
    }
}
